export default {
	data() {
		return {
			system_info: {}, //system info
			canvas_width: 0, //canvas width px
			canvas_height: 0, //canvas height px
			ctx: null, //canvas object
			canvas_id: null, //canvas id
			hidden: false, //Whether to hide canvas
			scale: 1, //canvas scale
			r_canvas_scale: 1,
			if_ctx: true
		}
	},
	methods: {
		/**
		 * save r-canvas.vue object
		 * @param {Object} that
		 */
		// saveThis(that){
		// 	rCanvasThis = that
		// },
		/**
		 * Draw round rect text
		 * @param {Object} config
		 * @param {Number} config.x x坐标
		 * @param {Number} config.y y坐标
		 * @param {Number} config.w 宽度
		 * @param {Number} config.h 高度
		 * @param {Number} config.radius 圆角弧度
		 * @param {String} config.fill_color 矩形颜色
		 */
		fillRoundRect(config) {
			return new Promise((resolve, reject) => {
				let x = this.compatibilitySize(parseFloat(config.x) * this.scale)
				let y = this.compatibilitySize(parseFloat(config.y) * this.scale)
				let w = this.compatibilitySize(parseFloat(config.w) * this.scale)
				let h = this.compatibilitySize(parseFloat(config.h) * this.scale)
				let radius = config.radius ? parseFloat(config.radius) * this.scale : 10 * this.scale

				let fill_color = config.fill_color || "black"
				// The diameter of the circle must be less than the width and height of the rectangle
				if (2 * radius > w || 2 * radius > h) {
					reject("The diameter of the circle must be less than the width and height of the rectangle")
					return false;
				}
				this.ctx.save();
				this.ctx.translate(x, y);
				//  
				this.drawRoundRectPath({
					w: w,
					h: h,
					radius: radius
				});
				this.ctx.fillStyle = fill_color
				this.ctx.fill();
				this.ctx.restore();
				resolve()
			})
		},
		/**
		 * Draws the sides of a rounded rectangle
		 * @param {Object} config
		 * @param {Number} config.w 宽度
		 * @param {Number} config.h 高度
		 * @param {Number} config.radius 圆角弧度
		 */
		drawRoundRectPath(config) {
			this.ctx.beginPath(0);
			this.ctx.arc(config.w - config.radius, config.h - config.radius, config.radius, 0, Math.PI / 2);
			this.ctx.lineTo(config.radius, config.h);
			this.ctx.arc(config.radius, config.h - config.radius, config.radius, Math.PI / 2, Math.PI);
			this.ctx.lineTo(0, config.radius);
			this.ctx.arc(config.radius, config.radius, config.radius, Math.PI, Math.PI * 3 / 2);
			this.ctx.lineTo(config.w - config.radius, 0);
			this.ctx.arc(config.w - config.radius, config.radius, config.radius, Math.PI * 3 / 2, Math.PI * 2);
			this.ctx.lineTo(config.w, config.h - config.radius);
			this.ctx.closePath();
		},
		/**
		 * Draw special Text,line wrapping is not supported
		 * @param {Object} config
		 * @param {String} config.text 文字
		 * @param {Number} config.x x坐标
		 * @param {Number} config.y y坐标
		 * @param {String} config.font_color 文字颜色
		 * @param {String} config.font_family 文字字体
		 * @param {Number} config.font_size 文字大小（px）
		 */
		drawSpecialText(params) {
			let general = params.general
			let list = params.list
			return new Promise(async (resolve, reject) => {
				if (!general) {
					reject("general cannot be empty:101")
					return;
				} else if (list && list.length > 0) {
					for (let i in list) {
						if (i != 0) {
							let font_size = list[i - 1].font_size ? parseFloat(list[i - 1].font_size) : 20
							this.ctx.setFontSize(font_size)
							general.x = parseFloat(general.x) + this.ctx.measureText(list[i - 1].text).width
						}
						list[i].x = general.x
						list[i].y = general.y + (list[i].margin_top ? parseFloat(list[i].margin_top) : 0)
						await this.drawText(list[i])
					}
					resolve()
				} else {
					reject("The length of config arr is less than 0")
					return;
				}

			})
		},
		/**
		 * array delete empty
		 * @param {Object} arr
		 */
		arrDeleteEmpty(arr) {
			let newArr = []
			for (let i in arr) {
				if (arr[i]) {
					newArr.push(arr[i])
				}
			}
			return newArr
		},
		/**
		 * Draw Text,support line
		 * @param {Object} config
		 * @param {String} config.text 文字
		 * @param {Number} config.max_width 文字最大宽度（大于宽度自动换行）
		 * @param {Number} config.line_height 文字上下行间距
		 * @param {Number} config.x x坐标
		 * @param {Number} config.y y坐标
		 * @param {String} config.font_color 文字颜色
		 * @param {String} config.font_family 文字字体 默认值：Arial
		 * @param {String} config.text_align 文字对齐方式（left/center/right）
		 * @param {Number} config.font_size 文字大小（px）
		 * @param {Boolean} config.line_through_height 中划线大小
		 * @param {Boolean} config.line_through_color 中划线颜色
		 * @param {String} config.font_style 规定文字样式
		 * @param {String} config.font_variant 规定字体变体
		 * @param {String} config.font_weight 规定字体粗细
		 * @param {String} config.line_through_cap 线末端类型
		 * @param {String} config.line_clamp 最大行数
		 * @param {String} config.line_clamp_hint 超过line_clamp后，尾部显示的自定义标识 如 ...
		 * @param {String} config.is_line_break 是否开启换行符换行
		 * 
		 */
		drawText(config, configuration = {}) {

			configuration['line_num'] = configuration.line_num ? configuration.line_num : 0
			configuration['text_width'] = configuration.text_width ? configuration.text_width : 0

			return new Promise(async (resolve, reject) => {

				if (config.text) {

					let draw_width = 0,
						draw_height = 0,
						draw_x = config.x,
						draw_y = config.y
					let font_size = config.font_size ? (parseFloat(config.font_size) * this.scale) : (20 *
						this.scale)
					let font_color = config.font_color || "#000"
					let font_family = config.font_family || "Arial"
					let line_height = config.line_height || config.font_size || 20
					let text_align = config.text_align || "left"
					let font_weight = config.font_weight || "normal"
					let font_variant = config.font_variant || "normal"
					let font_style = config.font_style || "normal"
					let line_clamp_hint = config.line_clamp_hint || '...'
					let lineBreakJoinText = ""
					let max_width = config.max_width ? parseFloat(config.max_width) * this.scale : 0
					// checkout is line break
					if (config.is_line_break) {
						let splitTextArr = config.text.split(/[\n]/g)
						if (splitTextArr && splitTextArr.length > 0) {
							let newSplitTextArr = this.arrDeleteEmpty(splitTextArr)
							if (newSplitTextArr && newSplitTextArr.length > 0) {
								lineBreakJoinText = newSplitTextArr.slice(1).join("\n")
								config.text = newSplitTextArr[0]
							} else {
								reject("Text cannot be empty:103")
								return
							}
						} else {
							reject("Text cannot be empty:102")
							return
						}
					}

					this.ctx.setFillStyle(font_color) // color
					this.ctx.textAlign = text_align;
					this.ctx.font =
						`${font_style} ${font_variant} ${font_weight} ${parseInt(font_size)}px ${font_family}`
					if (configuration.text_width >= this.ctx.measureText(config.text).width) {
						draw_width = configuration.text_width
					} else if (max_width > 0) {
						draw_width = max_width < this.ctx.measureText(config.text).width ? this
							.resetCompatibilitySize(max_width) : this.resetCompatibilitySize(this.ctx
								.measureText(config.text).width)
					} else {
						draw_width = this.ctx.measureText(config.text).width
					}
					configuration.text_width = draw_width / this.scale
					if (max_width && this.compatibilitySize(this.ctx.measureText(config.text).width) > this
						.compatibilitySize(max_width)) {
						let current_text = ""
						let text_arr = config.text.split("")
						for (let i in text_arr) {
							if (this.compatibilitySize(this.ctx.measureText(current_text + text_arr[i])
									.width) > this.compatibilitySize(max_width)) {
								// Hyphenation that is greater than the drawable width continues to draw
								if (config.line_clamp && parseInt(config.line_clamp) == 1) {
									// Subtracting the current_text tail width from the line_clamp_hint width
									let current_text_arr = current_text.split('')
									let json_current_text = ''
									while (true) {
										current_text_arr = current_text_arr.slice(1)
										json_current_text = current_text_arr.join('')
										if (this.compatibilitySize(this.ctx.measureText(json_current_text)
												.width) <= this.compatibilitySize(this.ctx.measureText(
												line_clamp_hint).width)) {

											current_text = current_text.replace(json_current_text, '')
											break;
										}
									}
									configuration.line_num += 1
									this.ctx.setFontSize(parseInt(this.compatibilitySize(
										font_size))) // font size
									this.ctx.fillText(current_text + line_clamp_hint, this
										.compatibilitySize(parseFloat(config.x) * this.scale), this
										.compatibilitySize(parseFloat(config.y) * this.scale));
								} else {
									configuration.line_num += 1
									this.ctx.setFontSize(parseInt(this.compatibilitySize(
										font_size))) // font size
									this.ctx.fillText(current_text, this.compatibilitySize(parseFloat(config
										.x) * this.scale), this.compatibilitySize(parseFloat(config
										.y) * this.scale));
									config.text = text_arr.slice(i).join("")
									config.y = config.y + line_height
									if (config.line_clamp) {
										config.line_clamp = parseInt(config.line_clamp) - 1
									}
									await this.drawText(config, configuration)
								}

								break;
							} else {
								current_text = current_text + text_arr[i]
							}
						}
					} else {
						if (config.line_through_height) {
							let x = parseFloat(config.x) * this.scale
							let w
							let y = parseFloat(config.y) * this.scale - (font_size / 2.6)
							if (text_align == "left") {
								w = this.ctx.measureText(config.text).width / 1.1 + parseFloat(config.x) *
									this.scale
							} else if (text_align == "right") {
								w = parseFloat(config.x) * this.scale - this.ctx.measureText(config.text)
									.width / 1.1
							} else if (text_align == "center") {
								x = parseFloat(config.x) * this.scale - this.ctx.measureText(config.text)
									.width / 1.1 / 2
								w = parseFloat(config.x) * this.scale + this.ctx.measureText(config.text)
									.width / 1.1 / 2
							}
							this.drawLineTo({
								x: x,
								y: y,
								w: w,
								h: y,
								line_width: config.line_through_height,
								line_color: config.line_through_color,
								line_cap: config.line_through_cap
							})
						}
						configuration.line_num += 1
						this.ctx.setFontSize(parseInt(this.compatibilitySize(font_size))) // font size
						this.ctx.fillText(config.text, this.compatibilitySize(parseFloat(config.x) * this
							.scale), this.compatibilitySize(parseFloat(config.y) * this.scale));
						if (config.line_clamp) {
							config.line_clamp = parseInt(config.line_clamp) - 1
						}
					}
					if (lineBreakJoinText) {
						await this.drawText({
							...config,
							text: lineBreakJoinText,
							y: config.y + line_height
						}, configuration)
					}
					draw_height = config.font_size * configuration.line_num
					draw_width = configuration.text_width
					resolve({
						draw_width,
						draw_height,
						draw_x,
						draw_y
					})
				} else {
					reject("Text cannot be empty:101")
				}
			})
		},
		/**
		 * Draw Line
		 * @param {Object} config
		 * @param {Object} config.x x坐标
		 * @param {Object} config.y y坐标
		 * @param {Object} config.w 线的宽度
		 * @param {Object} config.h 线的高度
		 * @param {Object} config.line_width 线的宽度
		 * @param {Object} config.line_color 线条颜色
		 */
		drawLineTo(config) {
			let x = this.compatibilitySize(config.x)
			let y = this.compatibilitySize(config.y)
			let w = this.compatibilitySize(config.w)
			let h = this.compatibilitySize(config.h)
			let line_width = config.line_width ? parseFloat(config.line_width) * this.scale : 1 * this.scale
			let line_color = config.line_color || "black"
			let line_cap = config.line_cap || "butt"
			this.ctx.beginPath()
			this.ctx.lineCap = line_cap
			this.ctx.lineWidth = line_width
			this.ctx.strokeStyle = line_color
			this.ctx.moveTo(x, y)
			this.ctx.lineTo(w, h)
			this.ctx.stroke()
		},
		/** 
		 * Compatibility px
		 * @param {Object} size
		 */
		compatibilitySize(size) {
			let canvasSize = (parseFloat(size) / 750) * this.system_info.windowWidth
			canvasSize = parseFloat(canvasSize * 2)
			return canvasSize
		},
		/**
		 * Restore compatibility px
		 * @param {Object} size
		 */
		resetCompatibilitySize(size) {
			let canvasSize = (parseFloat(size / 2) / this.system_info.windowWidth) * 750
			return canvasSize
		},
		/**
		 * Init canvas
		 */
		init(config) {
			return new Promise(async (resolve, reject) => {
				if (!config.canvas_id) {
					reject("Canvas ID cannot be empty, please refer to the usage example")
					return;
				}
				this.hidden = config.hidden
				this.canvas_id = config.canvas_id
				let system_info = await uni.getSystemInfoSync()
				this.system_info = system_info
				this.scale = config.scale && parseFloat(config.scale) > 0 ? parseInt(config.scale) : 1
				this.canvas_width = (config.canvas_width ? this.compatibilitySize(config.canvas_width) :
					system_info.windowWidth) * this.scale
				this.canvas_height = (config.canvas_height ? this.compatibilitySize(config.canvas_height) :
						system_info.windowHeight) * this.scale,
					this.r_canvas_scale = 1 / this.scale
				this.ctx = uni.createCanvasContext(this.canvas_id, this)
				this.setCanvasConfig({
					global_alpha: config.global_alpha ? parseFloat(config.global_alpha) : 1,
					backgroundColor: config.background_color ? config.background_color : "#fff"
				})
				resolve()
			})
		},
		/**
		 * clear canvas all path
		 */
		clearCanvas() {
			return new Promise(async (resolve, reject) => {
				if (!this.ctx) {
					reject("canvas is not initialized:101")
					return
				} else {
					this.ctx.clearRect(0, 0, parseFloat(this.canvas_width) * this.scale, parseFloat(this
						.canvas_height) * this.scale)
					await this.draw()
					resolve()
				}
			})
		},
		/**
		 * Set canvas config
		 * @param {Object} config
		 */
		setCanvasConfig(config) {
			this.ctx.globalAlpha = config.global_alpha
			this.ctx.fillStyle = config.backgroundColor
			this.ctx.fillRect(0, 0, parseFloat(this.canvas_width) * this.scale, parseFloat(this.canvas_height) * this
				.scale)
		},
		/**
		 * set canvas width
		 * @param {Object} width
		 */
		setCanvasWidth(width) {
			if (!width) {
				uni.showToast({
					title: 'setCanvasWidth：width error',
					icon: 'none'
				})
			}
			this.canvas_width = this.compatibilitySize(parseFloat(width)) * this.scale
			this.ctx.width = this.canvas_width
		},
		/**
		 * set canvas height
		 * @param {Object} height
		 */
		setCanvasHeight(height) {
			if (!height) {
				uni.showToast({
					title: 'setCanvasWidth：height error',
					icon: 'none'
				})
			}
			this.canvas_height = this.compatibilitySize(parseFloat(height)) * this.scale
			this.ctx.height = this.canvas_height
		},
		/**
		 * Draw to filepath
		 */
		draw(callback) {
			return new Promise((resolve, reject) => {
				let stop = setTimeout(() => {
					this.ctx.draw(false, setTimeout(() => {
						uni.canvasToTempFilePath({
							canvasId: this.canvas_id,
							quality: 1,
							success: (res) => {
								resolve(res)
								callback && callback(res)
							},
							fail: (err) => {
								reject(JSON.stringify(err) ||
									"Failed to generate poster:101")
							}
						}, this)
					}, 300))
					clearTimeout(stop)
				}, 300)
			})
		},
		/**
		 * draw rect
		 * @param {Number} config.x x坐标
		 * @param {Number} config.y y坐标
		 * @param {Number} config.w 图形宽度(px)
		 * @param {Number} config.h 图形高度(px)
		 * @param {Number} config.color 图形颜色
		 * @param {Number} config.is_radius 是否开启圆图（1.1.6及以下版本废弃，请使用border_radius）
		 * @param {Number} config.border_width 边框大小
		 * @param {Number} config.border_color 边框颜色
		 * 
		 */
		drawRect(config) {
			return new Promise(async (resolve, reject) => {
				if (!config.border_width || config.border_width <= 0) {
					config.border_width = 0
				} else {
					config.border_width = parseFloat(config.border_width)
				}
				if (parseFloat(config.border_width) > 0) {
					let sub_config = JSON.parse(JSON.stringify(config))
					sub_config.border_width = 0
					sub_config.w = config.w + config.border_width
					sub_config.h = config.h + config.border_width
					sub_config.color = config.border_color || 'black'
					if (sub_config.border_radius) {
						sub_config.border_radius = parseFloat(sub_config.border_radius) + parseFloat(config
							.border_width) / 2
					}
					await this.drawRect(sub_config)
				}

				let color = config.color || 'white'
				config.x = (parseFloat(config.x) + config.border_width / 2)
				config.y = (parseFloat(config.y) + config.border_width / 2)
				config['color'] = color
				this.ctx.fillStyle = color;
				if (config.is_radius || config.border_radius) {
					this.setNativeBorderRadius(config)
					this.ctx.fill()
				} else {
					this.ctx.fillRect(this.compatibilitySize(config.x * this.scale), this.compatibilitySize(
						config.y * this.scale), this.compatibilitySize(parseFloat(config.w) * this
						.scale), this.compatibilitySize(parseFloat(config.h) * this.scale))
				}
				resolve()
			})
		},
		/**
		 * Draw image
		 * @param {Object} config
		 * @param {String} config.url 图片链接
		 * @param {Number} config.x x坐标
		 * @param {Number} config.y y坐标
		 * @param {Number} config.w 图片宽度(px)
		 * @param {Number} config.h 图片高度(px)
		 * @param {Number} config.border_width 边大小
		 * @param {Number} config.border_color 边颜色
		 * @param {Number} config.is_radius 是否开启圆图（1.1.6及以下版本废弃，请使用border_radius）
		 * @param {Number} config.border_radius 圆角弧度
		 */
		drawImage(config) {
			return new Promise(async (resolve, reject) => {
				if (config.url) {
					let type = 0 // 1、network image  2、native image  3、base64 image
					let image_url
					let reg = /^http?/ig;
					if (reg.test(config.url)) {
						type = 1
					} else {
						if ((config.url.indexOf("data:image/png;base64") != -1) || config.url.indexOf(
								"data:image/jpeg;base64") != -1 || config.url.indexOf(
								"data:image/gif;base64") != -1) {
							type = 3
						} else {
							type = 2
						}
					}
					if (type == 1) {
						// network image
						await this.downLoadNetworkFile(config.url).then(res => { // two function
							image_url = res
						}).catch(err => {
							reject(err)
							return;
						})

					} else if (type == 2) {

						// native image
						const imageInfoResult = await uni.getImageInfo({
							src: config.url
						});
						try {
							if (imageInfoResult.length <= 1) {
								reject(imageInfoResult[0].errMsg + ':404')
								return
							}
						} catch (e) {
							reject(e + ':500')
							return
						}
						let base64 = await this.urlToBase64({
							url: imageInfoResult[1].path
						})
						// #ifdef MP-WEIXIN
						await this.base64ToNative({
							url: base64
						}).then(res => {
							image_url = res
						}).catch(err => {
							reject(JSON.stringify(err) + ":501")
							return;
						})
						// #endif
						// #ifndef MP-WEIXIN
						image_url = base64
						// #endif

					} else if (type == 3) {
						// #ifdef MP-WEIXIN
						await this.base64ToNative({
							url: config.url
						}).then(res => {
							image_url = res
						}).catch(err => {
							reject(JSON.stringify(err) + ":500")
							return;
						})
						// #endif
						// #ifndef MP-WEIXIN
						image_url = config.url
						// #endif
					} else {
						reject("Other Type Errors:101")
						return
					}
					if (config.border_width) {
						let border_radius = 0
						if (config.border_radius) {
							let multiple = config.w / config.border_radius
							border_radius = (parseFloat(config.w) + parseFloat(config.border_width)) /
								multiple
						}
						// drawRect
						await this.drawRect({
							x: parseFloat(config.x) - parseFloat(config.border_width) / 2,
							y: parseFloat(config.y) - parseFloat(config.border_width) / 2,
							w: parseFloat(config.w) + parseFloat(config.border_width),
							h: parseFloat(config.h) + parseFloat(config.border_width),
							color: config.border_color,
							border_radius: border_radius,
							border_width: config.border_width,
							is_radius: config.is_radius
						})
					}



					if (config.border_radius) {
						config.color = config.color ? config.color : 'rgba(0,0,0,0)'

						// 圆角有白边,+0.5的误差
						config.w = config.w + 0.3
						config.h = config.h + 0.3

						this.setNativeBorderRadius(config)
					} else if (config.is_radius) {
						//已废弃 is_radius
						this.ctx.setStrokeStyle("rgba(0,0,0,0)")
						this.ctx.save()
						this.ctx.beginPath()
						this.ctx.arc(this.compatibilitySize(parseFloat(config.x) * this.scale + parseFloat(
								config.w) * this.scale / 2), this.compatibilitySize(parseFloat(config
								.y) * this.scale + parseFloat(config.h) * this.scale / 2), this
							.compatibilitySize(parseFloat(config.w) * this.scale / 2), 0, 2 * Math.PI,
							false)
						this.ctx.stroke();
						this.ctx.clip()
					}

					await this.ctx.drawImage(image_url, this.compatibilitySize(parseFloat(config.x) * this
							.scale), this.compatibilitySize(parseFloat(config.y) * this.scale), this
						.compatibilitySize(parseFloat(config.w) * this.scale), this.compatibilitySize(
							parseFloat(config.h) * this.scale))
					this.ctx.restore() //Restore previously saved drawing context
					resolve()
				} else {
					let err_msg = "Links cannot be empty:101"
					reject(err_msg)
				}
			})
		},
		/**
		 * base64 to native available path
		 * @param {Object} config
		 */
		base64ToNative(config) {

			return new Promise((resolve, reject) => {
				let fileName = new Date().getTime()
				var filePath = `${wx.env.USER_DATA_PATH}/${fileName}_rCanvas.png`
				wx.getFileSystemManager().writeFile({
					filePath: filePath,
					data: config.url.replace(/^data:\S+\/\S+;base64,/, ''),
					encoding: 'base64',
					success: function() {
						resolve(filePath)
					},
					fail: function(error) {
						reject(error)
					}
				})
			})
		},
		/**
		 * native url to base64
		 * @param {Object} config
		 */
		urlToBase64(config) {
			return new Promise(async (resolve, reject) => {
				if (typeof window != 'undefined') {
					await this.downLoadNetworkFile(config.url).then(res => { // two function
						resolve(res)
					}).catch(err => {
						reject(err)
					})
				} else if (typeof plus != 'undefined') {
					plus.io.resolveLocalFileSystemURL(config.url, (obj) => {
						obj.file((file) => {
							let fileReader = new plus.io.FileReader()
							fileReader.onload = (res) => {
								resolve(res.target.result)
							}
							fileReader.onerror = (err) => {
								reject(err)
							}
							fileReader.readAsDataURL(file)
						}, (err) => {
							reject(err)
						})
					}, (err) => {
						reject(err)
					})
				} else if (typeof wx != 'undefined') {
					wx.getFileSystemManager().readFile({
						filePath: config.url,
						encoding: 'base64',
						success: function(res) {
							resolve('data:image/png;base64,' + res.data)
						},
						fail: function(error) {
							reject(error)
						}
					})
				}
			})
		},
		setNativeBorderRadius(config) {
			let border_radius = config.border_radius ? (parseFloat(config.border_radius) * this.scale) : (20 * this
				.scale)
			if ((parseFloat(config.w) * this.scale) < 2 * border_radius) border_radius = (parseFloat(config.w) * this
				.scale) / 2;
			if ((parseFloat(config.h) * this.scale) < 2 * border_radius) border_radius = (parseFloat(config.h) * this
				.scale) / 2;
			this.ctx.beginPath();
			this.ctx.moveTo(this.compatibilitySize((parseFloat(config.x) * this.scale) + border_radius), this
				.compatibilitySize((parseFloat(config.y) * this.scale)));
			this.ctx.arcTo(this.compatibilitySize((parseFloat(config.x) * this.scale) + (parseFloat(config.w) * this
					.scale)), this.compatibilitySize((parseFloat(config.y) * this.scale)), this.compatibilitySize((
					parseFloat(config.x) * this.scale) + (parseFloat(config.w) * this.scale)), this
				.compatibilitySize((parseFloat(config.y) * this.scale) + (parseFloat(config.h) * this.scale)), this
				.compatibilitySize(border_radius));
			this.ctx.arcTo(this.compatibilitySize((parseFloat(config.x) * this.scale) + (parseFloat(config.w) * this
					.scale)), this.compatibilitySize((parseFloat(config.y) * this.scale) + (parseFloat(config.h) *
					this.scale)), this.compatibilitySize((parseFloat(config.x) * this.scale)), this
				.compatibilitySize((parseFloat(config.y) * this.scale) + (parseFloat(config.h) * this.scale)), this
				.compatibilitySize(border_radius));
			this.ctx.arcTo((this.compatibilitySize(parseFloat(config.x) * this.scale)), this.compatibilitySize((
					parseFloat(config.y) * this.scale) + (parseFloat(config.h) * this.scale)), this
				.compatibilitySize((parseFloat(config.x) * this.scale)), this.compatibilitySize((parseFloat(config
					.y) * this.scale)), this.compatibilitySize(border_radius));
			this.ctx.arcTo(this.compatibilitySize((parseFloat(config.x) * this.scale)), this.compatibilitySize((
				parseFloat(config.y) * this.scale)), this.compatibilitySize((parseFloat(config.x) * this
				.scale) + (parseFloat(config.w) * this.scale)), this.compatibilitySize((parseFloat(config.y) *
				this.scale)), this.compatibilitySize(border_radius));
			this.ctx.closePath();
			this.ctx.strokeStyle = config.color || config.border_color || 'rgba(0,0,0,0)'; // 设置绘制边框的颜色
			this.ctx.stroke();
			this.ctx.save()
			this.ctx.clip();

		},
		/**
		 * Download network file
		 * @param {Object} url : download url
		 */
		downLoadNetworkFile(url) {
			return new Promise((resolve, reject) => {
				// #ifdef APP-PLUS
				uni.downloadFile({
					url,
					success: (res) => {
						if (res.statusCode == 200) {
							resolve(res.tempFilePath)
						} else {
							reject("Download Image Fail:102")
						}
					},
					fail: (err) => {
						reject("Download Image Fail:101")
					}
				})
				// #endif

				// #ifndef APP-PLUS
				// 解决图片在H5端报跨域问题
				var xhr = new XMLHttpRequest();

				xhr.open("get", url, true);
				if (url.indexOf('://images.xrwlswkjgs.com') > -1) {
					xhr.setRequestHeader("Cache-Control", "no-cache")
				}
				// 必须将返回类型设置为blob
				xhr.responseType = "blob";
				xhr.onload = function() {
					if (this.status == 200) {
						// 得到一个blob对象
						let blob = this.response;
						let file_reader = new FileReader();
						file_reader.readAsDataURL(blob);
						file_reader.onloadend = function(e) {
							resolve(file_reader.result);
						};
						file_reader.onerror = function(e) {
							reject("FileReader Image Fail:103")
						};

					} else {
						reject("Download Image Fail:101")
					}
				};
				xhr.onerror = function() {
					reject("Download Image Fail:101")
				}
				xhr.send();

				// #endif
			})
		},
		/**
		 * Save image to natice
		 * @param {Object} filePath ： native imageUrl
		 */
		saveImage(filePath) {
			return new Promise((resolve, reject) => {
				if (!filePath) {
					reject("FilePath cannot be null:101")
					return;
				}

				// #ifdef H5
				var str = Math.random().toString(36).slice(-6); // 生成随随机数
				var createA = document.createElement("a");
				// createA.download = filePath; // 修改前 
				createA.download = str; // 修改后
				createA.href = filePath;
				document.body.appendChild(createA);
				createA.click();
				createA.remove();
				resolve()
				// #endif

				// #ifndef H5
				uni.saveImageToPhotosAlbum({
					filePath: filePath,
					success: (res) => {
						resolve(res)
					},
					fail: (err) => {
						reject(err)
					}
				})
				// #endif
			})
		}
	}
}